package com.wzh.navcode.theadpool;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @author wangzhenghai
 */
@Slf4j
public class ThreadPoolManager {
    private static ScheduledThreadPoolExecutor scheduledExecutor;
    private static final Object LOCK = new Object();

    /**
     * 初始化线程池
     */
    private static void initializeExecutor() {
        synchronized (LOCK) {
            if (scheduledExecutor == null || scheduledExecutor.isShutdown()) {
                scheduledExecutor = new ScheduledThreadPoolExecutor(
                        Runtime.getRuntime().availableProcessors(),
                        r -> {
                            Thread thread = new Thread(r);
                            thread.setName("ScheduledTask-" + thread.getId());
                            return thread;
                        },
                        new ThreadPoolExecutor.CallerRunsPolicy()
                );
                // 设置一些额外的配置
                scheduledExecutor.setRemoveOnCancelPolicy(true);
                scheduledExecutor.setKeepAliveTime(60, TimeUnit.SECONDS);
            }
        }
    }

    /**
     * 修改scheduleAtFixedRate方法
     * @param command 原始任务
     * @param initialDelay 初始延迟
     * @param period 周期
     * @param unit 时间单位
     * @return ScheduledFuture
     */
    public static ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
        if (scheduledExecutor == null || scheduledExecutor.isShutdown()) {
            initializeExecutor();
        }
        try {
            return scheduledExecutor.scheduleAtFixedRate(
                    wrapRunnable(command),
                    initialDelay,
                    period,
                    unit
            );
        } catch (RejectedExecutionException e) {
            log.warn("Task rejected, trying to reinitialize executor");
            initializeExecutor();
            return scheduledExecutor.scheduleAtFixedRate(
                    wrapRunnable(command),
                    initialDelay,
                    period,
                    unit
            );
        }
    }

    /**
     * 包装Runnable以添加错误处理
     * @param command 原始任务
     * @return 包装后的任务
     */
    private static Runnable wrapRunnable(Runnable command) {
        return () -> {
            try {
                command.run();
            } catch (Exception e) {
                log.error("Error executing scheduled task", e);
            }
        };
    }

    /**
     * 优雅关闭线程池
     */
    public static void shutdown() {
        synchronized (LOCK) {
            if (scheduledExecutor != null && !scheduledExecutor.isShutdown()) {
                try {
                    scheduledExecutor.shutdown();
                    if (!scheduledExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
                        scheduledExecutor.shutdownNow();
                        if (!scheduledExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
                            log.error("Thread pool did not terminate");
                        }
                    }
                } catch (InterruptedException e) {
                    scheduledExecutor.shutdownNow();
                    Thread.currentThread().interrupt();
                } finally {
                    scheduledExecutor = null;
                }
            }
        }
    }

    /**
     * 检查线程池状态
     * @return 是否正在运行
     */
    public static boolean isRunning() {
        return scheduledExecutor != null && !scheduledExecutor.isShutdown();
    }
}